package com.jiangyifen.vmw.sdk;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.jiangyifen.vmw.sdk.command.AccessNumberDeleteCommand;
import com.jiangyifen.vmw.sdk.command.AccessNumberGatewayLinkCommand;
import com.jiangyifen.vmw.sdk.command.AccessNumberGetAllCommand;
import com.jiangyifen.vmw.sdk.command.AccessNumberRouteDeleteCommand;
import com.jiangyifen.vmw.sdk.command.AccessNumberRouteGetAllCommand;
import com.jiangyifen.vmw.sdk.command.AccessNumberRouteSaveCommand;
import com.jiangyifen.vmw.sdk.command.AccessNumberRouteUpdateCommand;
import com.jiangyifen.vmw.sdk.command.AccessNumberSaveCommand;
import com.jiangyifen.vmw.sdk.command.AccessNumberUpdateCommand;
import com.jiangyifen.vmw.sdk.command.AgentDeleteCommand;
import com.jiangyifen.vmw.sdk.command.AgentGetAllCommand;
import com.jiangyifen.vmw.sdk.command.AgentSaveCommand;
import com.jiangyifen.vmw.sdk.command.AgentSyncCommand;
import com.jiangyifen.vmw.sdk.command.BindCommand;
import com.jiangyifen.vmw.sdk.command.BlacklistDeleteCommand;
import com.jiangyifen.vmw.sdk.command.BlacklistGetAllCommand;
import com.jiangyifen.vmw.sdk.command.BlacklistSaveCommand;
import com.jiangyifen.vmw.sdk.command.BridgeCommand;
import com.jiangyifen.vmw.sdk.command.ChanSpyCommand;
import com.jiangyifen.vmw.sdk.command.ConferenceInviteCommand;
import com.jiangyifen.vmw.sdk.command.ConferenceKickCommand;
import com.jiangyifen.vmw.sdk.command.ConferenceLockCommand;
import com.jiangyifen.vmw.sdk.command.ConferenceMuteCommand;
import com.jiangyifen.vmw.sdk.command.ConferenceReInviteCommand;
import com.jiangyifen.vmw.sdk.command.ConferenceUnlockCommand;
import com.jiangyifen.vmw.sdk.command.ConferenceUnmuteCommand;
import com.jiangyifen.vmw.sdk.command.GatewayDeleteCommand;
import com.jiangyifen.vmw.sdk.command.GatewayGetAllCommand;
import com.jiangyifen.vmw.sdk.command.GatewaySaveCommand;
import com.jiangyifen.vmw.sdk.command.GatewayUpdateCommand;
import com.jiangyifen.vmw.sdk.command.GetBindInfoCommand;
import com.jiangyifen.vmw.sdk.command.GetCdrByCallUuidCommand;
import com.jiangyifen.vmw.sdk.command.GetCdrByUniqueidCommand;
import com.jiangyifen.vmw.sdk.command.GetCdrHangupDirectionByCallUuidCommand;
import com.jiangyifen.vmw.sdk.command.GetCdrHangupDirectionByUniqueidCommand;
import com.jiangyifen.vmw.sdk.command.GetChannelCommand;
import com.jiangyifen.vmw.sdk.command.GetChannelCountCommand;
import com.jiangyifen.vmw.sdk.command.GetChannelVariablesCommand;
import com.jiangyifen.vmw.sdk.command.GetConferenceStatusCommand;
import com.jiangyifen.vmw.sdk.command.GetGatewayStatusCommand;
import com.jiangyifen.vmw.sdk.command.GetMobileInfoCommand;
import com.jiangyifen.vmw.sdk.command.GetQueueStatusCommand;
import com.jiangyifen.vmw.sdk.command.GetQueueStatusLiteCommand;
import com.jiangyifen.vmw.sdk.command.GetSipCallIdToUuidCommand;
import com.jiangyifen.vmw.sdk.command.GetSipPhoneStatusCommand;
import com.jiangyifen.vmw.sdk.command.GetSipPhoneStatusLiteCommand;
import com.jiangyifen.vmw.sdk.command.HangupCommand;
import com.jiangyifen.vmw.sdk.command.HoldCommand;
import com.jiangyifen.vmw.sdk.command.IsExtenCommand;
import com.jiangyifen.vmw.sdk.command.IsPhoneNumberBlockInCommand;
import com.jiangyifen.vmw.sdk.command.IsPhoneNumberBlockOutCommand;
import com.jiangyifen.vmw.sdk.command.IvrNotifyTaskAsyncCommand;
import com.jiangyifen.vmw.sdk.command.IvrNotifyTaskAsyncLocalDialplanCommand;
import com.jiangyifen.vmw.sdk.command.IvrNotifyTaskCommand;
import com.jiangyifen.vmw.sdk.command.LoadConfigAndReloadAsteriskCommand;
import com.jiangyifen.vmw.sdk.command.LoadConfigAndRestartAsteriskCommand;
import com.jiangyifen.vmw.sdk.command.LoadQueueMemberDeleteOutboundNumberCommand;
import com.jiangyifen.vmw.sdk.command.LoadQueueMemberPauseCommand;
import com.jiangyifen.vmw.sdk.command.LoadQueueMemberSaveOutboundNumberCommand;
import com.jiangyifen.vmw.sdk.command.LoadQueueMemberSetSipPhoneOrAgentCommand;
import com.jiangyifen.vmw.sdk.command.LoadQueueMemberUnPauseCommand;
import com.jiangyifen.vmw.sdk.command.NotifyTaskCommand;
import com.jiangyifen.vmw.sdk.command.OriginateCommand;
import com.jiangyifen.vmw.sdk.command.OriginateLocalDialplanCommand;
import com.jiangyifen.vmw.sdk.command.QueueDeleteCommand;
import com.jiangyifen.vmw.sdk.command.QueueGetAllCommand;
import com.jiangyifen.vmw.sdk.command.QueueMemberDeleteOutboundNumberCommand;
import com.jiangyifen.vmw.sdk.command.QueueMemberPauseCommand;
import com.jiangyifen.vmw.sdk.command.QueueMemberSaveOutboundNumberCommand;
import com.jiangyifen.vmw.sdk.command.QueueMemberSetSipPhoneOrAgentCommand;
import com.jiangyifen.vmw.sdk.command.QueueMemberUnPauseCommand;
import com.jiangyifen.vmw.sdk.command.QueueSaveCommand;
import com.jiangyifen.vmw.sdk.command.QueueUpdateCommand;
import com.jiangyifen.vmw.sdk.command.RedirectCommand;
import com.jiangyifen.vmw.sdk.command.SipPhoneDeleteCommand;
import com.jiangyifen.vmw.sdk.command.SipPhoneGetAllCommand;
import com.jiangyifen.vmw.sdk.command.SipPhoneSaveCommand;
import com.jiangyifen.vmw.sdk.command.SipPhoneUpdateCommand;
import com.jiangyifen.vmw.sdk.command.SqeCommand;
import com.jiangyifen.vmw.sdk.command.TenantActionNodeTreeGetCommand;
import com.jiangyifen.vmw.sdk.command.TenantDeleteCommand;
import com.jiangyifen.vmw.sdk.command.TenantGetAllCommand;
import com.jiangyifen.vmw.sdk.command.TenantSaveCommand;
import com.jiangyifen.vmw.sdk.command.TenantUpdateCommand;
import com.jiangyifen.vmw.sdk.command.TtsCommand;
import com.jiangyifen.vmw.sdk.command.UnBindCommand;
import com.jiangyifen.vmw.sdk.command.UnHoldCommand;
import com.jiangyifen.vmw.sdk.command.VoiceVerificationCodeCommand;
import com.jiangyifen.vmw.sdk.command.bean.AccessNumber;
import com.jiangyifen.vmw.sdk.command.bean.AccessNumberRoute;
import com.jiangyifen.vmw.sdk.command.bean.Agent;
import com.jiangyifen.vmw.sdk.command.bean.Blacklist;
import com.jiangyifen.vmw.sdk.command.bean.Gateway;
import com.jiangyifen.vmw.sdk.command.bean.Queue;
import com.jiangyifen.vmw.sdk.command.bean.SipPhone;
import com.jiangyifen.vmw.sdk.command.bean.Tenant;
import com.jiangyifen.vmw.sdk.command.internal.AbstractApiCommand;
import com.jiangyifen.vmw.sdk.command.internal.AbstractApiResponse;
import com.jiangyifen.vmw.sdk.command.internal.SimpleResponse;
import com.jiangyifen.vmw.sdk.command.response.AccessNumberGetAllResponse;
import com.jiangyifen.vmw.sdk.command.response.AccessNumberRouteGetAllResponse;
import com.jiangyifen.vmw.sdk.command.response.AgentGetAllResponse;
import com.jiangyifen.vmw.sdk.command.response.AgentSipPhoneBindInfoResponse;
import com.jiangyifen.vmw.sdk.command.response.BlacklistGetAllResponse;
import com.jiangyifen.vmw.sdk.command.response.GatewayGetAllResponse;
import com.jiangyifen.vmw.sdk.command.response.GetCdrByCallUuidResponse;
import com.jiangyifen.vmw.sdk.command.response.GetCdrByUniqueidResponse;
import com.jiangyifen.vmw.sdk.command.response.GetCdrHangupDirectionByCallUuidResponse;
import com.jiangyifen.vmw.sdk.command.response.GetCdrHangupDirectionByUniqueidResponse;
import com.jiangyifen.vmw.sdk.command.response.GetChannelCountResponse;
import com.jiangyifen.vmw.sdk.command.response.GetChannelResponse;
import com.jiangyifen.vmw.sdk.command.response.GetChannelVariablesResponse;
import com.jiangyifen.vmw.sdk.command.response.GetConferenceStatusResponse;
import com.jiangyifen.vmw.sdk.command.response.GetGatewayStatusResponse;
import com.jiangyifen.vmw.sdk.command.response.GetMobileInfoResponse;
import com.jiangyifen.vmw.sdk.command.response.GetQueueStatusLiteResponse;
import com.jiangyifen.vmw.sdk.command.response.GetQueueStatusResponse;
import com.jiangyifen.vmw.sdk.command.response.GetSipCallIdToUuidResponse;
import com.jiangyifen.vmw.sdk.command.response.GetSipPhoneStatusLiteResponse;
import com.jiangyifen.vmw.sdk.command.response.GetSipPhoneStatusResponse;
import com.jiangyifen.vmw.sdk.command.response.IsExtenResponse;
import com.jiangyifen.vmw.sdk.command.response.IsPhoneNumberBlockInResponse;
import com.jiangyifen.vmw.sdk.command.response.IsPhoneNumberBlockOutResponse;
import com.jiangyifen.vmw.sdk.command.response.IvrNotifyTaskAsyncLocalDialplanResponse;
import com.jiangyifen.vmw.sdk.command.response.IvrNotifyTaskAsyncResponse;
import com.jiangyifen.vmw.sdk.command.response.IvrNotifyTaskResponse;
import com.jiangyifen.vmw.sdk.command.response.LoadConfigAndReloadAsteriskResponse;
import com.jiangyifen.vmw.sdk.command.response.LoadConfigAndRestartAsteriskResponse;
import com.jiangyifen.vmw.sdk.command.response.NotifyTaskResponse;
import com.jiangyifen.vmw.sdk.command.response.OriginateLocalDialplanResponse;
import com.jiangyifen.vmw.sdk.command.response.OriginateResponse;
import com.jiangyifen.vmw.sdk.command.response.QueueGetAllResponse;
import com.jiangyifen.vmw.sdk.command.response.QueueMemberPauseResponse;
import com.jiangyifen.vmw.sdk.command.response.SipPhoneGetAllResponse;
import com.jiangyifen.vmw.sdk.command.response.TenantActionNodeTreeGetResponse;
import com.jiangyifen.vmw.sdk.command.response.TenantGetAllResponse;
import com.jiangyifen.vmw.sdk.command.response.TtsResponse;
import com.jiangyifen.vmw.sdk.command.response.VoiceVerificationCodeResponse;
import com.jiangyifen.vmw.sdk.util.VmwSignUtil;

public class VmwServer {

	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	private String vmwUrl;
	private String apiSecret;
	private int connectTimeout = 2000;
	private int readTimeout = 2000;

	private SSLContext sslContext = null;

	public VmwServer() {
		try {
			sslContext = SSLContext.getInstance("TLS");
			sslContext.init(null, trustAllCerts, new SecureRandom());
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
	}

	public VmwServer(String vmwUrl, String apiSecret, int connectTimeout, int readTimeout) {
		this.vmwUrl = vmwUrl;
		this.apiSecret = apiSecret;
		this.connectTimeout = connectTimeout;
		this.readTimeout = readTimeout;
		try {
			sslContext = SSLContext.getInstance("TLS");
			sslContext.init(null, trustAllCerts, new SecureRandom());
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
	}

	public <T extends AbstractApiResponse> T sendCommand(AbstractApiCommand apiCommand, Class<T> clazz) {

		T t = null;

		try {

			String commandString = apiCommand.toJsonString();
			logger.debug("commandString=" + commandString);

			String urlString = vmwUrl + "?sign=" + VmwSignUtil.sign(commandString, apiSecret);
			logger.debug("request url=" + urlString);
			logger.debug("request body=" + commandString);
//			System.out.println(commandString);
			URL url = new URL(urlString);

			HttpsURLConnection.setDefaultHostnameVerifier(new NullHostNameVerifier());
			HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("POST");
			conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
			conn.setConnectTimeout(connectTimeout);
			conn.setReadTimeout(readTimeout);
			conn.setDoOutput(true);
			conn.connect();

			// send http request
			OutputStream outStream = conn.getOutputStream();
			outStream.write(commandString.getBytes());
			outStream.flush();
			outStream.close();

			// receive http response
			StringBuilder result = new StringBuilder();
			BufferedReader r = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			String line = null;
			while ((line = r.readLine()) != null) {
				result.append(line);
			}
			t = JSON.parseObject(result.toString(), clazz);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return t;
	}

	// private <T extends AbstractApiResponse> T sendCommand(AbstractApiCommand
	// apiCommand, Class<T> clazz) {
	// String commandString = apiCommand.toJsonString();
	// logger.debug("commandString="+commandString);
	// String url = vmwUrl + "?sign=" + VmwSignUtil.sign(commandString,
	// apiSecret);
	// logger.debug("request url="+url);
	// logger.debug("request body="+commandString);
	// HttpRequest httpRequest =
	// HttpRequest.post(url).contentType("application/json;charset=UTF-8")
	// .connectTimeout(connectTimeout).readTimeout(readTimeout).send(commandString);
	// httpRequest.trustAllCerts();
	// String body = httpRequest.body();
	// logger.debug("RESPONSE BODY="+body);
	// T t = JSON.parseObject(body, clazz);
	//
	// return t;
	// }

	public String getVmwUrl() {
		return vmwUrl;
	}

	public void setVmwUrl(String vmwUrl) {
		this.vmwUrl = vmwUrl;
	}

	public String getApiSecret() {
		return apiSecret;
	}

	public void setApiSecret(String apiSecret) {
		this.apiSecret = apiSecret;
	}

	public int getConnectTimeout() {
		return connectTimeout;
	}

	public void setConnectTimeout(int connectTimeout) {
		this.connectTimeout = connectTimeout;
	}

	public int getReadTimeout() {
		return readTimeout;
	}

	public void setReadTimeout(int readTimeout) {
		this.readTimeout = readTimeout;
	}

	/**
	 * 5.1 【新增Agent】<br>
	 * 
	 * @param agentAid
	 *            第三方应用中用户的唯一标识，一般是id或用户名
	 * @param agentName
	 *            姓名
	 * @param agentJobNumber
	 *            工号
	 * @return simpleResponse
	 */
	public SimpleResponse agentSave(Agent agent) {
		AgentSaveCommand request = new AgentSaveCommand(agent);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 5.1 【删除Agent】<br>
	 * 
	 * @param agentAidList
	 *            关于agentAid的list集合
	 * @return simpleResponse
	 */
	public SimpleResponse agentDelete(List<String> agentAidList) {
		AgentDeleteCommand request = new AgentDeleteCommand(agentAidList);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 5.1 【同步Agent】<br>
	 * 
	 * @param agentAidList
	 * @return
	 */
	public SimpleResponse agentSync(List<Agent> agentList) {
		return agentSync(0L, agentList);
	}

	public SimpleResponse agentSync(Long tenantId, List<Agent> agentList) {
		AgentSyncCommand request = new AgentSyncCommand(tenantId, agentList);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 5.1 【获取所有Agent】<br>
	 * 
	 * @return agentListAllResponse
	 */
	public AgentGetAllResponse agentGetAll(Long tenantId) {
		AgentGetAllCommand request = new AgentGetAllCommand(tenantId);
		AgentGetAllResponse response = this.sendCommand(request, AgentGetAllResponse.class);
		return response;
	}

	public AgentGetAllResponse agentGetAll() {
		return agentGetAll(0L);
	}

	/**
	 * 5.2 【绑定】<br>
	 * 用途：将Agent和SipPhone建立“一对一对的应关系”告诉vmw“哪个Agent在使用哪个SipPhone”。<br>
	 * 调用时机：在用户登录时调用【绑定】<br>
	 * 
	 * @param agentAid
	 *            第三方应用中用户的唯一标识，一般是id或用户名
	 * @param sipPhoneName
	 *            所要绑定的SIPPHONE的分机号
	 * @return simpleResponse
	 */
	public SimpleResponse bind(String agentAid, String sipPhoneName) {
		BindCommand request = new BindCommand(agentAid, sipPhoneName);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 5.2 【解绑】<br>
	 * 用途：将Agent和SipPhone建立“一对一对的应关系”告诉vmw“哪个Agent在使用哪个SipPhone”。<br>
	 * 调用时机：在用户注销时调用【解绑】<br>
	 * 
	 * @param agentAid
	 *            第三方应用中用户的唯一标识，一般是id或用户名
	 * @param sipPhoneName
	 *            所要绑定的SIPPHONE的分机号
	 * @return simpleResponse
	 */
	public SimpleResponse unBind(String agentAid, String sipPhoneName) {

		UnBindCommand request = new UnBindCommand(agentAid, sipPhoneName);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);

		return response;
	}

	/**
	 * 5.3 【绑定关系查询】<br>
	 * 用途：查询Agent和SipPhone的绑定关系 <br>
	 * 
	 * @param agentAid
	 *            第三方应用中用户的唯一标识，一般是id或用户名
	 * @param sipPhoneName
	 *            所要绑定的SIPPHONE的分机号
	 * @return agentSipPhoneBindInfoResponse
	 */
	public AgentSipPhoneBindInfoResponse getBindInfo(String agentAid, String sipPhoneName) {

		GetBindInfoCommand request = new GetBindInfoCommand(agentAid, sipPhoneName);
		AgentSipPhoneBindInfoResponse response = this.sendCommand(request, AgentSipPhoneBindInfoResponse.class);

		return response;
	}

	/**
	 * 5.4 【置忙】 <br>
	 * 用途：将Agent的状态设置为“忙” <br>
	 * 调用时机：Agent在界面上点击“置忙”的按钮或链接时调用。 <br>
	 * 效果：处于“忙”状态的Agent将不会接到“技能组”分配的呼入电话 <br>
	 * 
	 * @param queueMemberInterface
	 *            技能组成员所使用的设备拨号字符串，格式为：SIP/${sipPhoneName}
	 * @param reason
	 *            置忙原因
	 * @return simpleResponse
	 */
	public QueueMemberPauseResponse queueMemberPause(String queueMemberInterface, String reason) {
		QueueMemberPauseCommand request = new QueueMemberPauseCommand(queueMemberInterface, reason);
		QueueMemberPauseResponse response = this.sendCommand(request, QueueMemberPauseResponse.class);
		return response;
	}

	/**
	 * 5.4 【置闲】<br>
	 * 用途：将Agent的状态设置为“闲” <br>
	 * 调用时机：Agent在界面上点击“置闲”的按钮或链接时调用。 <br>
	 * 效果：处于“忙”状态的Agent将不会接到“技能组”分配的呼入电话 <br>
	 * 
	 * @param queueMemberInterface
	 *            技能组成员所使用的设备拨号字符串，格式为：SIP/${sipPhoneName}
	 * @return simpleResponse
	 */
	public QueueMemberPauseResponse queueMemberUnPause(String queueMemberInterface) {
		QueueMemberUnPauseCommand request = new QueueMemberUnPauseCommand(queueMemberInterface);
		QueueMemberPauseResponse response = this.sendCommand(request, QueueMemberPauseResponse.class);
		return response;
	}

	/**
	 * 5.5 【实时并发数查询】<br>
	 * 用途：查询系统当前的并发通话Channe的总数<br>
	 * 调用时机：一般在发起呼叫前调用，用来判断系统的负载，决定是否要发起呼叫<br>
	 * 
	 * @return getChannelCountResponse
	 */
	public GetChannelCountResponse getChannelCount() {
		GetChannelCountCommand request = new GetChannelCountCommand();
		GetChannelCountResponse response = this.sendCommand(request, GetChannelCountResponse.class);
		return response;
	}

	/**
	 * 5.6 【发起呼叫】<br>
	 * 
	 * @param absoluteTimeout
	 *            通话超时时间（秒）。超时后自动挂断。0为永不超时
	 * @param src
	 *            第一路呼叫的号码
	 * @param srcRingTimeout 振铃时长
	 * @param srcGateway
	 *            第一路呼叫所需要走的gateway。若src为内部分机号，则此字段无需填写
	 * @param srcAccessNumber
	 *            第一路呼叫所需要用的主叫号。若src为内部分机号，则此字段无需填写
	 * @param srcCallerIdName
	 *            第一路呼叫所需要用的主叫（显示用）
	 * @param srcCallerIdNumber
	 *            第一路呼叫所需要用的主叫（显示用）
	 * @param srcAnnounceMediaUrl
	 *            第一路呼叫接通后所听到的提示音
	 * @param dst
	 *            第二路呼叫的号码
	 * @param dstGateway
	 *            第二路呼叫所需要走的gateway。若dst为内部分机号，则此字段无需填写
	 * @param dstAccessNumber
	 *            第二路呼叫所需要用的主叫号。若dst为内部分机号，则此字段无需填写
	 * @param dstAnnounceMediaUrl
	 *            第二路呼叫接通后所听到的提示音
	 * @param userData
	 *            自定义数据。会随CdrEvent返回
	 * @return originateResponse
	 */
	public OriginateResponse originate(Long tenantId, Integer absoluteTimeout, String src,Long srcRingTimeout, String srcGateway,
			String srcAccessNumber, String srcCallerIdName, String srcCallerIdNumber, String srcAnnounceMediaUrl,
			String dst, String dstGateway, String dstAccessNumber, String dstAnnounceMediaUrl, String userData) {
		OriginateCommand request = new OriginateCommand(tenantId, absoluteTimeout, src,srcRingTimeout, srcGateway, srcAccessNumber,
				srcCallerIdName, srcCallerIdNumber, srcAnnounceMediaUrl, dst, dstGateway, dstAccessNumber,
				dstAnnounceMediaUrl, userData);
		OriginateResponse response = this.sendCommand(request, OriginateResponse.class);
		return response;
	}

	public OriginateResponse originate(Long tenantId, Integer absoluteTimeout, String src,Long srcRingTimeout, String srcGateway,
			String srcAccessNumber, String srcAnnounceMediaUrl, String dst, String dstGateway, String dstAccessNumber,
			String dstAnnounceMediaUrl) {
		return originate(tenantId, absoluteTimeout, src,srcRingTimeout, srcGateway, srcAccessNumber, "", "", srcAnnounceMediaUrl, dst,
				dstGateway, dstAccessNumber, dstAnnounceMediaUrl, "");
	}

	public OriginateResponse originate(Long tenantId, String src, String dst) {
		return originate(tenantId, 0, src,60000L, "", "", "", "", "", dst, "", "", "", "");
	}
	
	/**
     * 5.28 【发起呼叫本地拨号计划】<br>
     * 
     * @param absoluteTimeout
     *            通话超时时间（秒）。超时后自动挂断。0为永不超时
     * @param dialplanExten
     *            第一路呼叫的号码
     * @param dst
     *            第二路呼叫的号码
     * @param dstGateway
     *            第二路呼叫所需要走的gateway。若dst为内部分机号，则此字段无需填写
     * @param dstAccessNumber
     *            第二路呼叫所需要用的主叫号。若dst为内部分机号，则此字段无需填写
     * @param dstAnnounceMediaUrl
     *            第二路呼叫接通后所听到的提示音
     * @param userData
     *            自定义数据。会随CdrEvent返回
     * @return originateResponse
     */
    public OriginateLocalDialplanResponse originateLocalDialplan(Long tenantId, Integer absoluteTimeout, String src, String srcGateway, String srcAccessNumber, String dialplanExten,String dst, String dstGateway, String dstAccessNumber, String userData) {
        OriginateLocalDialplanCommand request = new OriginateLocalDialplanCommand(tenantId, absoluteTimeout, src, srcGateway, srcAccessNumber, dialplanExten, dst, dstGateway, dstAccessNumber,userData);
        OriginateLocalDialplanResponse response = this.sendCommand(request, OriginateLocalDialplanResponse.class);
        return response;
    }

	/**
	 * 5.7 【获取指定SipPhone的当前Channel】<br>
	 * 用途：获取sipPhone的channel以及正在和该sipPhone通话的channel<br>
	 * 
	 * @param sipPhoneName
	 *            sipPhone的分机号
	 * @return getChannelResponse
	 */
	public GetChannelResponse getChannel(String sipPhoneName) {
		GetChannelCommand request = new GetChannelCommand(sipPhoneName);
		GetChannelResponse response = this.sendCommand(request, GetChannelResponse.class);
		return response;
	}

	/**
	 * 5.8 【呼叫保持、恢复】<br>
	 * 
	 * @param channel
	 *            希望挂断的channel名称
	 * @return simpleResponse
	 */
	public SimpleResponse hold(String sipPhoneName) {
		HoldCommand request = new HoldCommand(sipPhoneName);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 5.8 【呼叫保持、恢复】<br>
	 * 
	 * @param channel
	 *            希望挂断的channel名称
	 * @return simpleResponse
	 */
	public SimpleResponse unhold(String sipPhoneName) {
		UnHoldCommand request = new UnHoldCommand(sipPhoneName);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 5.9 【桥接通话】
	 * 
	 * @param channel1
	 * @param channel2
	 * @return
	 */
	public SimpleResponse bridge(String channel1, String channel2) {
		BridgeCommand request = new BridgeCommand(channel1, channel2);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 5.10 【转接Channel】<br>
	 * 用途：将制定的通话转接到指定的exten<br>
	 * 
	 * @param channel
	 *            希望转接的channel名称
	 * @param exten
	 *            希望将channel转接到的目标分机号
	 * @return simpleResponse
	 */
	public SimpleResponse redirect(String channel, String context, String exten) {
		return redirect(channel, context, exten, "", "", "");
	}

	/**
	 * 5.10 【转接Channel】<br>
	 * 用途：将制定的通话转接到指定的exten<br>
	 * 
	 * @param channel
	 * @param exten
	 * @param extraChannel
	 * @param extraExten
	 * @return
	 */
	public SimpleResponse redirect(String channel, String context, String exten, String extraContext,
			String extraChannel, String extraExten) {
		return redirect(channel, context, exten, "", "", extraChannel, extraContext, extraExten, "", "");
	}

	/**
	 * 5.10 【转接Channel】<br>
	 * 用途：将制定的通话转接到指定的exten<br>
	 * 
	 * @param channel
	 * @param exten
	 * @param dstGateway
	 * @param dstAccessNumber
	 * @param extraChannel
	 * @param extraExten
	 * @param extraDstGateway
	 * @param extraDstAccessNumber
	 * @return
	 */
	public SimpleResponse redirect(String channel, String context, String exten, String dstGateway,
			String dstAccessNumber, String extraChannel, String extraContext, String extraExten, String extraDstGateway,
			String extraDstAccessNumber) {
		RedirectCommand request = new RedirectCommand(channel, context, exten, dstGateway, dstAccessNumber,
				extraChannel, extraContext, extraExten, extraDstGateway, extraDstAccessNumber);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 5.11 【挂断Channel】<br>
	 * 
	 * @param channel
	 *            希望挂断的channel名称
	 * @return simpleResponse
	 */
	public SimpleResponse hangup(String channel) {
		HangupCommand request = new HangupCommand(channel);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 5.12 【获取所有SipPhone状态】<br>
	 * 
	 * @return getSipPhoneStatusResponse
	 */
	public GetSipPhoneStatusResponse getSipPhoneStatus() {
		GetSipPhoneStatusCommand request = new GetSipPhoneStatusCommand();
		GetSipPhoneStatusResponse response = this.sendCommand(request, GetSipPhoneStatusResponse.class);
		return response;
	}
	
	public GetSipPhoneStatusLiteResponse getSipPhoneStatusLite() {
        GetSipPhoneStatusLiteCommand request = new GetSipPhoneStatusLiteCommand();
        GetSipPhoneStatusLiteResponse response = this.sendCommand(request, GetSipPhoneStatusLiteResponse.class);
        return response;
    }

	/**
	 * 5.13 【获取所有Gateway状态】
	 * 
	 * @return
	 */
	public GetGatewayStatusResponse getGatewayStatus() {
		GetGatewayStatusCommand request = new GetGatewayStatusCommand();
		GetGatewayStatusResponse response = this.sendCommand(request, GetGatewayStatusResponse.class);
		return response;
	}

	/**
	 * 5.14 【获取所有技能组状态】<br>
	 * 
	 * @return getQueueStatusResponse
	 */
	public GetQueueStatusResponse getQueueStatus() {
		GetQueueStatusCommand request = new GetQueueStatusCommand();
		GetQueueStatusResponse response = this.sendCommand(request, GetQueueStatusResponse.class);
		return response;
	}
	
	/**
     * 5.14 【获取简化版所有技能组状态】<br>
     * 
     * @return getQueueStatusResponse
     */
	public GetQueueStatusLiteResponse getQueueStatusLite() {
        GetQueueStatusLiteCommand request = new GetQueueStatusLiteCommand();
        GetQueueStatusLiteResponse response = this.sendCommand(request, GetQueueStatusLiteResponse.class);
        return response;
    }

	/**
	 * 5.15 【查询归属地】<br>
	 * 
	 * @param mobilePhoneNumber
	 * @return getMobileInfoResponse
	 */
	public GetMobileInfoResponse getMobileInfo(String mobilePhoneNumber) {
		GetMobileInfoCommand request = new GetMobileInfoCommand(mobilePhoneNumber);
		GetMobileInfoResponse response = this.sendCommand(request, GetMobileInfoResponse.class);
		return response;
	}

	/**
	 * 5.16 【查询Cdr】<br>
	 * 
	 * @param mobilePhoneNumber
	 * @return getMobileInfoResponse
	 */
	public GetCdrByUniqueidResponse getCdrByUniqueid(String uniqueid) {
		GetCdrByUniqueidCommand request = new GetCdrByUniqueidCommand(uniqueid);
		GetCdrByUniqueidResponse response = this.sendCommand(request, GetCdrByUniqueidResponse.class);
		return response;
	}

	/**
	 * 5.16 【查询Cdr】<br>
	 * 
	 * @param mobilePhoneNumber
	 * @return getMobileInfoResponse
	 */
	public GetCdrByCallUuidResponse getCdrByCallUuid(String uuid) {
		GetCdrByCallUuidCommand request = new GetCdrByCallUuidCommand(uuid);
		GetCdrByCallUuidResponse response = this.sendCommand(request, GetCdrByCallUuidResponse.class);
		return response;
	}

	/**
	 * 5.17 【服务质量评价】<br>
	 * 
	 * @param sqeSipPhoneName
	 * @param sqeQuestion
	 * @param sqeThankyou
	 * @return
	 */
	public SimpleResponse sqe(String sqeSipPhoneName, String sqeQuestion, String sqeThankyou) {
		SqeCommand request = new SqeCommand(sqeSipPhoneName, sqeQuestion, sqeThankyou);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 5.18 【判断分机号是否内部exten】<br>
	 * 
	 * @param exten
	 * @return
	 */
	public IsExtenResponse isExten(String exten) {
		IsExtenCommand request = new IsExtenCommand(exten);
		IsExtenResponse response = this.sendCommand(request, IsExtenResponse.class);
		return response;
	}

	/**
	 * 5.19 【监听】
	 * 
	 * @param spySipPhoneName
	 * @param spiedSipPhoneName
	 * @return
	 */
	public SimpleResponse chanSpy(String spySipPhoneName, String spiedSipPhoneName) {
		ChanSpyCommand chanSpyCommand = new ChanSpyCommand(spySipPhoneName, spiedSipPhoneName);
		SimpleResponse simpleResponse = this.sendCommand(chanSpyCommand, SimpleResponse.class);
		return simpleResponse;
	}

	/**
	 * 5.20 【语音验证码】
	 * 
	 * @return
	 */
	public VoiceVerificationCodeResponse voiceVerificationCode(Long tenantId, String phoneNumber,Long phoneNumberRingTimeout, String gateway,
			String accessNumber, String exten, String media1, String code, String media2, Integer repeat,
			Integer absoluteTimeout) {
		VoiceVerificationCodeCommand request = new VoiceVerificationCodeCommand(tenantId, phoneNumber,phoneNumberRingTimeout, gateway,
				accessNumber, exten, media1, code, media2, repeat, absoluteTimeout);
		VoiceVerificationCodeResponse response = this.sendCommand(request, VoiceVerificationCodeResponse.class);
		return response;
	}

	public GetChannelVariablesResponse getChannelVariables() {
		GetChannelVariablesCommand request = new GetChannelVariablesCommand();
		GetChannelVariablesResponse response = this.sendCommand(request, GetChannelVariablesResponse.class);
		return response;
	}
	
	public GetSipCallIdToUuidResponse getSipCallIdToUuid() {
	    GetSipCallIdToUuidCommand request = new GetSipCallIdToUuidCommand();
	    GetSipCallIdToUuidResponse response = this.sendCommand(request, GetSipCallIdToUuidResponse.class);
        return response;
    }

	////////////////////////////////////////////////////////////////////////////////////////////////

	/**
	 * 【租户权限树】获取
	 * 
	 * @return
	 */
	public TenantActionNodeTreeGetResponse tenantActionNodeTreeGet() {
		TenantActionNodeTreeGetCommand apiCommand = new TenantActionNodeTreeGetCommand();
		TenantActionNodeTreeGetResponse response = this.sendCommand(apiCommand, TenantActionNodeTreeGetResponse.class);
		return response;
	}

	/**
	 * 【租户】增
	 * 
	 * @return
	 */
	public SimpleResponse tenantSave(Tenant tenant) {
		TenantSaveCommand request = new TenantSaveCommand(tenant);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 【租户】删
	 * 
	 * @return
	 */
	public SimpleResponse tenantDelete(List<Long> ids) {
		TenantDeleteCommand request = new TenantDeleteCommand(ids);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 【租户】改
	 * 
	 * @return
	 */
	public SimpleResponse tenantUpdate(Tenant tenant) {
		TenantUpdateCommand request = new TenantUpdateCommand(tenant);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 【租户】查
	 * 
	 * @return
	 */
	public TenantGetAllResponse tenantGetAll() {
		TenantGetAllCommand apiCommand = new TenantGetAllCommand();
		TenantGetAllResponse response = this.sendCommand(apiCommand, TenantGetAllResponse.class);
		return response;
	}

	/**
	 * 添加接入号
	 * 
	 * @param accessNumber
	 * @return
	 */
	public SimpleResponse accessNumberSave(AccessNumber accessNumber) {
		AccessNumberSaveCommand request = new AccessNumberSaveCommand(accessNumber);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 删除接入号
	 * 
	 * @param ids
	 * @return
	 */
	public SimpleResponse accessNumberDelete(List<Long> ids) {
		AccessNumberDeleteCommand request = new AccessNumberDeleteCommand(ids);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 更新接入号
	 * 
	 * @param accessNumber
	 * @return
	 */
	public SimpleResponse accessNumberUpdate(AccessNumber accessNumber) {
		AccessNumberUpdateCommand request = new AccessNumberUpdateCommand(accessNumber);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 获取接入号
	 * 
	 * @return
	 */
	public AccessNumberGetAllResponse accessNumberGetAll() {
		AccessNumberGetAllCommand apiCommand = new AccessNumberGetAllCommand();
		AccessNumberGetAllResponse response = this.sendCommand(apiCommand, AccessNumberGetAllResponse.class);
		return response;
	}

	/**
	 * 添加网关
	 * 
	 * @param gateway
	 * @return
	 */
	public SimpleResponse gatewaySave(Gateway gateway) {
		GatewaySaveCommand request = new GatewaySaveCommand(gateway);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 删除网关
	 * 
	 * @param ids
	 * @return
	 */
	public SimpleResponse gatewayDelete(List<Long> ids) {
		GatewayDeleteCommand request = new GatewayDeleteCommand(ids);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 更新网关
	 * 
	 * @param gateway
	 * @return
	 */
	public SimpleResponse gatewayUpdate(Gateway gateway) {
		GatewayUpdateCommand request = new GatewayUpdateCommand(gateway);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 获取所有网关
	 * 
	 * @return
	 */
	public GatewayGetAllResponse gatewayGetAll() {
		GatewayGetAllCommand apiCommand = new GatewayGetAllCommand();
		GatewayGetAllResponse response = this.sendCommand(apiCommand, GatewayGetAllResponse.class);
		return response;
	}

	/**
	 * 删除网关接入号对应关系
	 * 
	 * @param accessNumberId
	 * @param gatewayIdList
	 * @return
	 */
	public SimpleResponse accessNumberGatewayLink(Long accessNumberId, List<Long> gatewayIdList) {
		AccessNumberGatewayLinkCommand apiCommand = new AccessNumberGatewayLinkCommand(accessNumberId, gatewayIdList);
		SimpleResponse response = this.sendCommand(apiCommand, SimpleResponse.class);
		return response;
	}

	/**
	 * 添加分机
	 * 
	 * @param sipPhone
	 * @return
	 */
	public SimpleResponse sipPhoneSave(SipPhone sipPhone) {
		SipPhoneSaveCommand request = new SipPhoneSaveCommand(sipPhone);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 删除分机
	 * 
	 * @param ids
	 * @return
	 */
	public SimpleResponse sipPhoneDelete(List<Long> ids) {
		SipPhoneDeleteCommand request = new SipPhoneDeleteCommand(ids);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 更新分机
	 * 
	 * @param sipPhone
	 * @return
	 */
	public SimpleResponse sipPhoneUpdate(SipPhone sipPhone) {
		SipPhoneUpdateCommand request = new SipPhoneUpdateCommand(sipPhone);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 获取分机
	 * 
	 * @return
	 */
	public SipPhoneGetAllResponse sipPhoneGetAll() {
		SipPhoneGetAllCommand apiCommand = new SipPhoneGetAllCommand();
		SipPhoneGetAllResponse response = this.sendCommand(apiCommand, SipPhoneGetAllResponse.class);
		return response;
	}

	/**
	 * 保存接入路由
	 * 
	 * @param accessNumberRoute
	 * @return
	 */
	public SimpleResponse accessNumberRouteSave(AccessNumberRoute accessNumberRoute) {
		AccessNumberRouteSaveCommand request = new AccessNumberRouteSaveCommand(accessNumberRoute);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 删除接入路由
	 * 
	 * @param ids
	 * @return
	 */
	public SimpleResponse accessNumberRouteDelete(List<Long> ids) {
		AccessNumberRouteDeleteCommand request = new AccessNumberRouteDeleteCommand(ids);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 更新接入路由
	 * 
	 * @param accessNumberRoute
	 * @return
	 */
	public SimpleResponse accessNumberRouteUpdate(AccessNumberRoute accessNumberRoute) {
		AccessNumberRouteUpdateCommand request = new AccessNumberRouteUpdateCommand(accessNumberRoute);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 获取接入路由
	 * 
	 * @return
	 */
	public AccessNumberRouteGetAllResponse accessNumberRouteGetAll() {
		AccessNumberRouteGetAllCommand apiCommand = new AccessNumberRouteGetAllCommand();
		AccessNumberRouteGetAllResponse response = this.sendCommand(apiCommand, AccessNumberRouteGetAllResponse.class);
		return response;
	}

	/**
	 * 添加剂能组
	 * 
	 * @param queue
	 * @return
	 */
	public SimpleResponse queueSave(Queue queue) {
		QueueSaveCommand request = new QueueSaveCommand(queue);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 删除技能组
	 * 
	 * @param ids
	 * @return
	 */
	public SimpleResponse queueDelete(List<Long> ids) {
		QueueDeleteCommand request = new QueueDeleteCommand(ids);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 更新技能组
	 * 
	 * @param queue
	 * @return
	 */
	public SimpleResponse queueUpdate(Queue queue) {
		QueueUpdateCommand request = new QueueUpdateCommand(queue);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 获取技能组
	 * 
	 * @return
	 */
	public QueueGetAllResponse queueGetAll() {
		QueueGetAllCommand apiCommand = new QueueGetAllCommand();
		QueueGetAllResponse response = this.sendCommand(apiCommand, QueueGetAllResponse.class);
		return response;
	}

	/**
	 * 保存技能组成员接入号
	 * 
	 * @param queueId
	 * @param outboundNumber
	 * @param gatewayName
	 * @param penalty
	 * @return
	 */
	public SimpleResponse queueMemberSaveOutboundNumber(Long queueId, String outboundNumber, String gatewayName,
			Integer penalty) {
		QueueMemberSaveOutboundNumberCommand request = new QueueMemberSaveOutboundNumberCommand(queueId, outboundNumber,
				gatewayName, penalty);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 删除技能组成员的接入号
	 * 
	 * @param queueId
	 * @param outboundNumberId
	 * @return
	 */
	public SimpleResponse queueMemberDeleteOutboundNumber(Long queueId, Long outboundNumberId) {
		QueueMemberDeleteOutboundNumberCommand request = new QueueMemberDeleteOutboundNumberCommand(queueId,
				outboundNumberId);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 设置技能组的分机或座席
	 * 
	 * @param queueId
	 * @param sipPhoneIdList
	 * @param agentAidList
	 * @return
	 */
	public SimpleResponse queueMemberSetSipPhoneOrAgent(Long queueId, List<Long> sipPhoneIdList,
			List<String> agentAidList) {
		QueueMemberSetSipPhoneOrAgentCommand request = new QueueMemberSetSipPhoneOrAgentCommand(queueId, sipPhoneIdList,
				agentAidList);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 添加黑名单
	 * 
	 * @param blacklist
	 * @return
	 */
	public SimpleResponse blacklistSave(Blacklist blacklist) {
		BlacklistSaveCommand request = new BlacklistSaveCommand(blacklist);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 删除黑名单
	 * 
	 * @param ids
	 * @return
	 */
	public SimpleResponse blacklistDelete(List<Long> ids) {
		BlacklistDeleteCommand request = new BlacklistDeleteCommand(ids);
		SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
		return response;
	}

	/**
	 * 所有黑名单
	 * 
	 * @return
	 */
	public BlacklistGetAllResponse blacklistGetAll() {
		BlacklistGetAllCommand apiCommand = new BlacklistGetAllCommand();
		BlacklistGetAllResponse response = this.sendCommand(apiCommand, BlacklistGetAllResponse.class);
		return response;
	}

	/**
	 * 呼出黑名单
	 * 
	 * @param tenantId
	 * @param phoneNumber
	 * @return
	 */
	public IsPhoneNumberBlockOutResponse isPhoneNumberBlockOut(Long tenantId, String phoneNumber) {
		IsPhoneNumberBlockOutCommand apiCommand = new IsPhoneNumberBlockOutCommand(tenantId, phoneNumber);
		IsPhoneNumberBlockOutResponse response = this.sendCommand(apiCommand, IsPhoneNumberBlockOutResponse.class);
		return response;
	}

	/**
	 * 呼入黑名单
	 * 
	 * @param tenantId
	 * @param phoneNumber
	 * @return
	 */
	public IsPhoneNumberBlockInResponse isPhoneNumberBlockIn(Long tenantId, String phoneNumber) {
		IsPhoneNumberBlockInCommand apiCommand = new IsPhoneNumberBlockInCommand(tenantId, phoneNumber);
		IsPhoneNumberBlockInResponse response = this.sendCommand(apiCommand, IsPhoneNumberBlockInResponse.class);
		return response;
	}

	/**
	 * 查询会议的状态
	 * 
	 * @return
	 */
	public GetConferenceStatusResponse getConferenceStatus(String exten) {
		GetConferenceStatusCommand apiCommand = new GetConferenceStatusCommand(exten);
		GetConferenceStatusResponse response = this.sendCommand(apiCommand, GetConferenceStatusResponse.class);
		return response;
	}

	/**
	 * 会议室成员邀请
	 * @param exten
	 * @param gateway
	 * @param accessNumber
	 * @param phoneNumberList
	 * @param phoneNumberRingTimeout 振铃时长
	 * @return
	 */
	public SimpleResponse conferenceInvite(String exten,String gateway, String accessNumber,List<String> phoneNumberList,Long phoneNumberRingTimeout) {
		ConferenceInviteCommand apiCommand = new ConferenceInviteCommand( exten, gateway,  accessNumber, phoneNumberList,phoneNumberRingTimeout);
		SimpleResponse response = this.sendCommand(apiCommand, SimpleResponse.class);
		return response;
	}
	
	/**
	 * 会议室成员重新邀请
	 * 
	 * @return
	 */
	public SimpleResponse conferenceReInvite(String exten, String phoneNUmber,Long phoneNumberRingTimeout) {
		ConferenceReInviteCommand apiCommand = new ConferenceReInviteCommand(exten, phoneNUmber,phoneNumberRingTimeout);
		SimpleResponse response = this.sendCommand(apiCommand, SimpleResponse.class);
		return response;
	}

	/**
	 * 会议室成员踢出
	 * 
	 * @return
	 */
	public SimpleResponse conferenceKick(String exten, String channel) {
		ConferenceKickCommand apiCommand = new ConferenceKickCommand(exten, channel);
		SimpleResponse response = this.sendCommand(apiCommand, SimpleResponse.class);
		return response;
	}

	/**
	 * 会议室成员静音
	 * 
	 * @return
	 */
	public SimpleResponse conferenceMute(String exten, String channel) {
		ConferenceMuteCommand apiCommand = new ConferenceMuteCommand(exten, channel);
		SimpleResponse response = this.sendCommand(apiCommand, SimpleResponse.class);
		return response;
	}

	/**
	 * 会议室成员解除静音
	 * 
	 * @return
	 */
	public SimpleResponse conferenceUnMute(String exten, String channel) {
		ConferenceUnmuteCommand apiCommand = new ConferenceUnmuteCommand(exten, channel);
		SimpleResponse response = this.sendCommand(apiCommand, SimpleResponse.class);
		return response;
	}
	
	/**
	 * 会议室锁定
	 * 
	 * @return
	 */
	public SimpleResponse conferenceLock(String exten) {
		ConferenceLockCommand apiCommand = new ConferenceLockCommand(exten);
		SimpleResponse response = this.sendCommand(apiCommand, SimpleResponse.class);
		return response;
	}
	
	/**
	 * 会议室解锁
	 * 
	 * @return
	 */
	public SimpleResponse conferenceUnlock(String exten) {
		ConferenceUnlockCommand apiCommand = new ConferenceUnlockCommand(exten);
		SimpleResponse response = this.sendCommand(apiCommand, SimpleResponse.class);
		return response;
	}
	
	/**
     * tts语音合成
     * 
     * @return
     */
    public TtsResponse tts(Long tenantId,String content) {
        TtsCommand apiCommand = new TtsCommand(tenantId,content);
        TtsResponse response = this.sendCommand(apiCommand, TtsResponse.class);
        return response;
    }
    
    /**
     * 获取挂断方
     * 
     * @return
     */
    public GetCdrHangupDirectionByCallUuidResponse getCdrHangupDirectionByCallUuid(String callUuid) {
        GetCdrHangupDirectionByCallUuidCommand apiCommand = new GetCdrHangupDirectionByCallUuidCommand(callUuid);
        GetCdrHangupDirectionByCallUuidResponse response = this.sendCommand(apiCommand, GetCdrHangupDirectionByCallUuidResponse.class);
        return response;
    }
    
    /**
     * 获取挂断方
     * 
     * @return
     */
    public GetCdrHangupDirectionByUniqueidResponse getCdrHangupDirectionByUniqueid(String uniqueid) {
        GetCdrHangupDirectionByUniqueidCommand apiCommand = new GetCdrHangupDirectionByUniqueidCommand(uniqueid);
        GetCdrHangupDirectionByUniqueidResponse response = this.sendCommand(apiCommand, GetCdrHangupDirectionByUniqueidResponse.class);
        return response;
    }
    
    /**
     * 语音通知
     * @param tenantId 租户编号 默认值 0
     * @param playbacksize 播放次数
     * @param src 语音通知号码
     * @param srcRingTimeout 振铃时长
     * @param srcGateway 语音通知使用的网关
     * @param srcAccessNumber 语音通知使用的接入号
     * @param srcCallerIdName 第一路呼叫所需要用的主叫（显示用）
     * @param srcCallerIdNumber 第一路呼叫所需要用的主叫（显示用）
     * @param filePath 语音通知使用的系统文件 不带后缀 "/vmw/resource/media/longterm/e2fb8505a14d4321ae4b7ed1cea11dc0" 后缀".wav"
     * @param content 语音通知的文字内容 ，如果语音通知使用的系统文件不为空就已filePath首选，如果filePath为空，则是用content语音合成，两者不可都为空。
     * @param userData 自定义标记内容，json格式字符串{}
     * @return
     */
    public NotifyTaskResponse notifyTask(Integer repeat, String phoneNumber,Long srcRingTimeout, String srcGateway, String srcAccessNumber, String srcCallerIdName,String srcCallerIdNumber, String content, String userData) {
        NotifyTaskCommand request = new NotifyTaskCommand(repeat, phoneNumber,srcRingTimeout, srcGateway, srcAccessNumber, srcCallerIdName,srcCallerIdNumber,content, userData);
        NotifyTaskResponse response = this.sendCommand(request, NotifyTaskResponse.class);
        return response;
    }
    
    /**
     * IVR动态语音通知
     * @param phoneNumber
     * @param phoneNumberRingTimeout 振铃时长
     * @param srcGateway
     * @param srcAccessNumber
     * @param srcCallerIdName
     * @param srcCallerIdNumber
     * @param userData
     * @return
     */
    public IvrNotifyTaskResponse ivrNotifyTask(String phoneNumber,Long phoneNumberRingTimeout, String srcGateway, String srcAccessNumber, String ivrExten,String notifyTaskPlayFileUrl, String userData) {
        IvrNotifyTaskCommand request = new IvrNotifyTaskCommand(phoneNumber,phoneNumberRingTimeout, srcGateway, srcAccessNumber, ivrExten, notifyTaskPlayFileUrl, userData);
        IvrNotifyTaskResponse response = this.sendCommand(request, IvrNotifyTaskResponse.class);
        return response;
    }
    
    /**
     * IVR动态语音通知【异步下载语音文件】
     * @param phoneNumber
     * @param phoneNumberRingTimeout
     * @param srcGateway
     * @param srcAccessNumber
     * @param srcCallerIdName
     * @param srcCallerIdNumber
     * @param userData
     * @return
     */
    public IvrNotifyTaskAsyncResponse ivrNotifyTaskAsync(String phoneNumber,Long phoneNumberRingTimeout, String srcGateway, String srcAccessNumber, String ivrExten,String notifyTaskPlayFileUrl, String userData) {
        IvrNotifyTaskAsyncCommand request = new IvrNotifyTaskAsyncCommand(phoneNumber,phoneNumberRingTimeout, srcGateway, srcAccessNumber, ivrExten, notifyTaskPlayFileUrl, userData);
        IvrNotifyTaskAsyncResponse response = this.sendCommand(request, IvrNotifyTaskAsyncResponse.class);
        return response;
    }
    
    /**
     * IVR动态语音通知【异步下载语音文件】本地Local方案
     * @param dialplanExten
     * @param phoneNumber
     * @param phoneNumberRingTimeout
     * @param srcGateway
     * @param srcAccessNumber
     * @param srcCallerIdName
     * @param srcCallerIdNumber
     * @param userData
     * @return
     */
    public IvrNotifyTaskAsyncLocalDialplanResponse ivrNotifyTaskAsyncLocalDialplan(String dialplanExten,String phoneNumber,Long phoneNumberRingTimeout, String srcGateway, String srcAccessNumber, String ivrExten,String notifyTaskPlayFileUrl, String userData) {
    	IvrNotifyTaskAsyncLocalDialplanCommand request = new IvrNotifyTaskAsyncLocalDialplanCommand(dialplanExten,phoneNumber,phoneNumberRingTimeout, srcGateway, srcAccessNumber, ivrExten, notifyTaskPlayFileUrl, userData);
        IvrNotifyTaskAsyncLocalDialplanResponse response = this.sendCommand(request, IvrNotifyTaskAsyncLocalDialplanResponse.class);
        return response;
    }
    
    /**
     * 同步数据asterisk reload
     * @return
     */
    public LoadConfigAndReloadAsteriskResponse loadConfigAndReloadAsterisk() {
        LoadConfigAndReloadAsteriskCommand request = new LoadConfigAndReloadAsteriskCommand();
        LoadConfigAndReloadAsteriskResponse response = this.sendCommand(request, LoadConfigAndReloadAsteriskResponse.class);
        return response;
    }
    
    /**
     * 同步数据asterisk Restart
     * @return
     */
    public LoadConfigAndRestartAsteriskResponse loadConfigAndRestartAsterisk() {
        LoadConfigAndRestartAsteriskCommand request = new LoadConfigAndRestartAsteriskCommand();
        LoadConfigAndRestartAsteriskResponse response = this.sendCommand(request, LoadConfigAndRestartAsteriskResponse.class);
        return response;
    }
    
    /**
     * 同步数据 【置忙】 <br>
     * 用途：将Agent的状态设置为“忙” <br>
     * 调用时机：Agent在界面上点击“置忙”的按钮或链接时调用。 <br>
     * 效果：处于“忙”状态的Agent将不会接到“技能组”分配的呼入电话 <br>
     * 
     * @param queueMemberInterface
     *            技能组成员所使用的设备拨号字符串，格式为：SIP/${sipPhoneName}
     * @param reason
     *            置忙原因
     * @return simpleResponse
     */
    public QueueMemberPauseResponse loadQueueMemberPause(String queueMemberInterface, String reason) {
        LoadQueueMemberPauseCommand request = new LoadQueueMemberPauseCommand(queueMemberInterface, reason);
        QueueMemberPauseResponse response = this.sendCommand(request, QueueMemberPauseResponse.class);
        return response;
    }

    /**
     * 同步数据 【置闲】<br>
     * 用途：将Agent的状态设置为“闲” <br>
     * 调用时机：Agent在界面上点击“置闲”的按钮或链接时调用。 <br>
     * 效果：处于“忙”状态的Agent将不会接到“技能组”分配的呼入电话 <br>
     * 
     * @param queueMemberInterface
     *            技能组成员所使用的设备拨号字符串，格式为：SIP/${sipPhoneName}
     * @return simpleResponse
     */
    public QueueMemberPauseResponse loadQueueMemberUnPause(String queueMemberInterface) {
        LoadQueueMemberUnPauseCommand request = new LoadQueueMemberUnPauseCommand(queueMemberInterface);
        QueueMemberPauseResponse response = this.sendCommand(request, QueueMemberPauseResponse.class);
        return response;
    }
    
    /**
     * 同步数据 保存技能组成员接入号
     * 
     * @param queueId
     * @param outboundNumber
     * @param gatewayName
     * @param penalty
     * @return
     */
    public SimpleResponse loadQueueMemberSaveOutboundNumber(Long queueId, String outboundNumber, String gatewayName,
            Integer penalty) {
        LoadQueueMemberSaveOutboundNumberCommand request = new LoadQueueMemberSaveOutboundNumberCommand(queueId, outboundNumber,
                gatewayName, penalty);
        SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
        return response;
    }

    /**
     * 同步数据 删除技能组成员的接入号
     * 
     * @param queueId
     * @param outboundNumberId
     * @return
     */
    public SimpleResponse loadQueueMemberDeleteOutboundNumber(Long queueId, Long outboundNumberId) {
        LoadQueueMemberDeleteOutboundNumberCommand request = new LoadQueueMemberDeleteOutboundNumberCommand(queueId,
                outboundNumberId);
        SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
        return response;
    }

    /**
     * 同步数据 设置技能组的分机或座席
     * 
     * @param queueId
     * @param sipPhoneIdList
     * @param agentAidList
     * @return
     */
    public SimpleResponse loadQueueMemberSetSipPhoneOrAgent(Long queueId, List<Long> sipPhoneIdList,
            List<String> agentAidList) {
        LoadQueueMemberSetSipPhoneOrAgentCommand request = new LoadQueueMemberSetSipPhoneOrAgentCommand(queueId, sipPhoneIdList,
                agentAidList);
        SimpleResponse response = this.sendCommand(request, SimpleResponse.class);
        return response;
    }

	///////////// http https ////////////////
	private static TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
		@Override
		public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
		}

		@Override
		public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
		}

		@Override
		public X509Certificate[] getAcceptedIssuers() {
			return null;
		}
	} };

	private class NullHostNameVerifier implements HostnameVerifier {
		@Override
		public boolean verify(String arg0, SSLSession arg1) {
			return true;
		}
	}

}
